package com.bolt.core.view.components;

import com.bolt.convention.exception.ServiceException;
import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

/**
 * 　表单模板装饰类
 *
 * @author mi
 */
public class Decorate {

    private final Log logger = LogFactory.getLog(getClass());

    private String openTemplate;

    private String closeTemplate;

    private final ComponentsBase component;


    public Decorate(String start, String end, ComponentsBase component) {
        openTemplate = start;
        closeTemplate = end;
        this.component = component;
    }

    public Decorate(ComponentsBase component) {

        this.component = component;

    }

    private void buildTemplate(String templateContext, Writer writer) throws IOException {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_0);
        StringTemplateLoader stringLoader = new StringTemplateLoader();
        stringLoader.putTemplate("myTemplate", templateContext);
        cfg.setTemplateLoader(stringLoader);
        StringWriter output = new StringWriter();
        try {
            Template template = cfg.getTemplate("myTemplate", "utf-8");
            Map root = new HashMap();
            root.put("tag", component);

            final Writer wrapped = writer;
            writer = new Writer() {
                @Override
                public void write(char[] cbuf, int off, int len) throws IOException {
                    wrapped.write(cbuf, off, len);
                }

                @Override
                public void flush() throws IOException {
                    // nothing!
                }

                @Override
                public void close() throws IOException {
                    wrapped.close();
                }
            };


            template.process(root, writer);
            //return output.toString();
        } catch (Exception ex) {
            logger.error(ex);
            throw new ServiceException(ex);
        } finally {
            try {
                output.close();
            } catch (IOException ex) {
                logger.error(ex);
                throw new ServiceException(ex);
            }
        }
    }



    public void start(HttpServletRequest req, HttpServletResponse res, Writer writer) {
        try {
            buildTemplate(this.openTemplate,writer);
           if(null != component) {
               component.start(req,res,writer);
           }
        } catch (Exception e) {
            logger.error(e);
        }
    }


    public void end(HttpServletRequest req, HttpServletResponse res, Writer writer) {
        try {
            if(null != component) {
                component.end(req, res, writer);
            }
            buildTemplate(this.closeTemplate,writer);
        } catch (Exception e) {
            logger.error(e);
        }

    }


    public static Decorate buildRowDecorate() {
        Decorate row = new Decorate("<div class=\"bolt-form-item\">", "</div>", null);

        return row;
    }

    public static Decorate buildFormColumnDecorate(FormItem item) {
        Decorate column = new Decorate("<#assign parameters = tag.parameters/>\n" +
                "<#if parameters.block??>\n" +
                "<label>${tag.label?default(\"&nbsp;\")}</label>\n" +
                "<#elseif tag.singleColumn>\n" +
                "<label class=\"bolt-form-label\">${tag.label?default(\"&nbsp;\")}</label>\n" +
                "<div class=\"bolt-input-block\">\n" +
                "<#else>"+
                "<div class=\"bolt-inline\">\n" +
                "    <label class=\"bolt-form-label\">${tag.label?default(\"&nbsp;\")}</label>\n" +
                "    <div class=\"bolt-input-inline\">\n" +
                "</#if>", "<#assign parameters = tag.parameters/>\n" +
                "<#if tag.singleColumn>\n" +
                "</div>\n" +
                "<#if parameters.caption??><div class=\"bolt-form-mid\">${parameters.caption}</div></#if>\n" +
                "<#else>\n" +
                "</div>\n" +
                "<#if parameters.caption??><div class=\"bolt-form-mid\">${parameters.caption}</div></#if>\n" +
                "</div>\n" +
                "</#if>", item);

        return column;
    }
    public static Decorate buildCombinationForm(FormItem item){
        Decorate  decorate = new Decorate("<div class=\"form-inline\">","</div>",item);
        return decorate;

    }


    public static Decorate buildQueryFormColumnDecorate(FormItem item) {
        Decorate column = new Decorate("<div class=\"form-group\">", "</div>", item);

        return column;
    }


}
